home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / uucp-104.lha / uucp-1.04 / uulog.c < prev    next >
C/C++ Source or Header  |  1993-02-13  |  10KB  |  445 lines

  1. /* uulog.c
  2.    Display the UUCP log file.
  3.  
  4.    Copyright (C) 1991, 1992 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #if USE_RCS_ID
  29. const char uulog_rcsid[] = "$Id: uulog.c,v 1.11 1992/12/17 05:23:00 ian Rel $";
  30. #endif
  31.  
  32. #include <ctype.h>
  33. #include <errno.h>
  34.  
  35. #include "getopt.h"
  36.  
  37. #include "uudefs.h"
  38. #include "uuconf.h"
  39. #include "system.h"
  40.  
  41. /* This is a pretty bad implementation of uulog, which I don't think
  42.    is a very useful program anyhow.  It only takes a single -s and/or
  43.    -u switch.  When using HAVE_HDB_LOGGING it requires a system.  */
  44.  
  45. /* The program name.  */
  46. char abProgram[] = "uulog";
  47.  
  48. /* Local functions.  */
  49.  
  50. static void ulusage P((void));
  51.  
  52. /* Long getopt options.  */
  53. static const struct option asLlongopts[] = { { NULL, 0, NULL, 0 } };
  54.  
  55. int
  56. main (argc, argv)
  57.      int argc;
  58.      char **argv;
  59. {
  60.   /* -D: display Debug file */
  61.   boolean fdebug = FALSE;
  62.   /* -f: keep displaying lines forever.  */
  63.   boolean fforever = FALSE;
  64.   /* -n lines: number of lines to display.  */
  65.   int cshow = 0;
  66.   /* -s: system name.  */
  67.   const char *zsystem = NULL;
  68.   /* -S: display Stats file */
  69.   boolean fstats = FALSE;
  70.   /* -u: user name.  */
  71.   const char *zuser = NULL;
  72.   /* -I: configuration file name.  */
  73.   const char *zconfig = NULL;
  74.   /* -x: display uuxqt log file.  */
  75.   boolean fuuxqt = FALSE;
  76.   int i;
  77.   int iopt;
  78.   pointer puuconf;
  79.   int iuuconf;
  80.   const char *zlogfile;
  81.   const char *zstatsfile;
  82.   const char *zdebugfile;
  83.   const char *zfile;
  84.   FILE *e;
  85.   char **pzshow = NULL;
  86.   int ishow = 0;
  87.   size_t csystem = 0;
  88.   size_t cuser = 0;
  89.   char *zline;
  90.   size_t cline;
  91.  
  92.   /* Look for a straight number argument, and convert it to -n before
  93.      passing the arguments to getopt.  */
  94.   for (i = 0; i < argc; i++)
  95.     {
  96.       if (argv[i][0] == '-' && isdigit (argv[i][1]))
  97.     {
  98.       size_t clen;
  99.       char *znew;
  100.  
  101.       clen = strlen (argv[i]);
  102.       znew = zbufalc (clen + 2);
  103.       znew[0] = '-';
  104.       znew[1] = 'n';
  105.       memcpy (znew + 2, argv[i] + 1, clen);
  106.       argv[i] = znew;
  107.     }
  108.     }
  109.  
  110.   while ((iopt = getopt_long (argc, argv, "Df:FI:n:s:Su:xX:", asLlongopts,
  111.                   (int *) NULL)) != EOF)
  112.     {
  113.       switch (iopt)
  114.     {
  115.     case 'D':
  116.       /* Show debugging file.  */
  117.       fdebug = TRUE;
  118.       break;
  119.  
  120.     case 'f':
  121.       /* Keep displaying lines forever for a particular system.  */
  122.       fforever = TRUE;
  123.       zsystem = optarg;
  124.       if (cshow == 0)
  125.         cshow = 10;
  126.       break;
  127.  
  128.     case 'F':
  129.       /* Keep displaying lines forever.  */
  130.       fforever = TRUE;
  131.       if (cshow == 0)
  132.         cshow = 10;
  133.       break;
  134.  
  135.     case 'I':
  136.       /* Configuration file name.  */
  137.       if (fsysdep_other_config (optarg))
  138.         zconfig = optarg;
  139.       break;
  140.  
  141.     case 'n':
  142.       /* Number of lines to display.  */
  143.       cshow = (int) strtol (optarg, (char **) NULL, 10);
  144.       break;
  145.  
  146.     case 's':
  147.       /* System name.  */
  148.       zsystem = optarg;
  149.       break;
  150.  
  151.     case 'S':
  152.       /* Show statistics file.  */
  153.       fstats = TRUE;
  154.       break;
  155.  
  156.     case 'u':
  157.       /* User name.  */
  158.       zuser = optarg;
  159.       break;
  160.  
  161.     case 'x':
  162.       /* Display uuxqt log file.  */
  163.       fuuxqt = TRUE;
  164.       break;
  165.  
  166.     case 'X':
  167. #if DEBUG > 1
  168.       /* Set debugging level.  */
  169.       iDebug |= idebug_parse (optarg);
  170. #endif
  171.       break;
  172.  
  173.     case 0:
  174.       /* Long option found and flag set.  */
  175.       break;
  176.  
  177.     default:
  178.       ulusage ();
  179.       break;
  180.     }
  181.     }
  182.  
  183.   if (optind != argc || (fstats && fdebug))
  184.     ulusage ();
  185.  
  186.   iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig);
  187.   if (iuuconf != UUCONF_SUCCESS)
  188.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  189.  
  190. #if DEBUG > 1
  191.   {
  192.     const char *zdebug;
  193.  
  194.     iuuconf = uuconf_debuglevel (puuconf, &zdebug);
  195.     if (iuuconf != UUCONF_SUCCESS)
  196.       ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  197.     if (zdebug != NULL)
  198.       iDebug |= idebug_parse (zdebug);
  199.   }
  200. #endif
  201.  
  202.   iuuconf = uuconf_logfile (puuconf, &zlogfile);
  203.   if (iuuconf != UUCONF_SUCCESS)
  204.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  205.  
  206.   iuuconf = uuconf_statsfile (puuconf, &zstatsfile);
  207.   if (iuuconf != UUCONF_SUCCESS)
  208.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  209.  
  210.   iuuconf = uuconf_debugfile (puuconf, &zdebugfile);
  211.   if (iuuconf != UUCONF_SUCCESS)
  212.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  213.  
  214.   usysdep_initialize (puuconf, 0);
  215.  
  216.   if (zsystem != NULL)
  217.     {
  218. #if HAVE_HDB_LOGGING
  219.       if (strcmp (zsystem, "ANY") != 0)
  220. #endif
  221.     {
  222.       struct uuconf_system ssys;
  223.  
  224.       iuuconf = uuconf_system_info (puuconf, zsystem, &ssys);
  225.       if (iuuconf != UUCONF_SUCCESS)
  226.         {
  227.           if (iuuconf != UUCONF_NOT_FOUND)
  228.         ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  229.           ulog (LOG_FATAL, "%s: System not found", zsystem);
  230.         }
  231.       zsystem = zbufcpy (ssys.uuconf_zname);
  232.       (void) uuconf_system_free (puuconf, &ssys);
  233.     }
  234.     }
  235.  
  236.   if (fstats)
  237.     zfile = zstatsfile;
  238.   else if (fdebug)
  239.     zfile = zdebugfile;
  240.   else
  241.     {
  242. #if ! HAVE_HDB_LOGGING
  243.       zfile = zlogfile;
  244. #else
  245.       const char *zprogram;
  246.       char *zalc;
  247.  
  248.       /* We need a system to find a HDB log file.  */
  249.       if (zsystem == NULL)
  250.     ulusage ();
  251.  
  252.       if (fuuxqt)
  253.     zprogram = "uuxqt";
  254.       else
  255.     zprogram = "uucico";
  256.  
  257.       zalc = zbufalc (strlen (zlogfile)
  258.               + strlen (zprogram)
  259.               + strlen (zsystem)
  260.               + 1);
  261.       sprintf (zalc, zlogfile, zprogram, zsystem);
  262.       zfile = zalc;
  263.  
  264.       if (strcmp (zsystem, "ANY") == 0)
  265.     zsystem = NULL;
  266. #endif
  267.     }
  268.  
  269.   e = fopen (zfile, "r");
  270.   if (e == NULL)
  271.     {
  272.       ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno));
  273.       usysdep_exit (FALSE);
  274.     }
  275.  
  276.   if (cshow > 0)
  277.     {
  278.       pzshow = (char **) xmalloc (cshow * sizeof (char *));
  279.       for (ishow = 0; ishow < cshow; ishow++)
  280.     pzshow[ishow] = NULL;
  281.       ishow = 0;
  282.     }
  283.  
  284.   /* Read the log file and output the appropriate lines.  */
  285.   if (zsystem != NULL)
  286.     csystem = strlen (zsystem);
  287.  
  288.   if (zuser != NULL)
  289.     cuser = strlen (zuser);
  290.  
  291.   zline = NULL;
  292.   cline = 0;
  293.  
  294.   while (TRUE)
  295.     {
  296.       while (getline (&zline, &cline, e) > 0)
  297.     {
  298.       char *zluser, *zlsys, *znext;
  299.       size_t cluser, clsys;
  300.  
  301.       /* Skip any leading whitespace (not that there should be
  302.          any).  */
  303.       znext = zline + strspn (zline, " \t");
  304.  
  305.       if (! fstats)
  306.         {
  307. #if ! HAVE_TAYLOR_LOGGING
  308.           /* The user name is the first field on the line.  */
  309.           zluser = znext;
  310.           cluser = strcspn (znext, " \t");
  311. #endif
  312.       
  313.           /* Skip the first field.  */
  314.           znext += strcspn (znext, " \t");
  315.           znext += strspn (znext, " \t");
  316.  
  317.           /* The system is the second field on the line.  */
  318.           zlsys = znext;
  319.           clsys = strcspn (znext, " \t");
  320.  
  321.           /* Skip the second field.  */
  322.           znext += clsys;
  323.           znext += strspn (znext, " \t");
  324.  
  325. #if HAVE_TAYLOR_LOGGING
  326.           /* The user is the third field on the line.  */
  327.           zluser = znext;
  328.           cluser = strcspn (znext, " \t");
  329. #endif
  330.         }
  331.       else
  332.         {
  333. #if ! HAVE_HDB_LOGGING
  334.           /* The user name is the first field on the line, and the
  335.          system name is the second.  */
  336.           zluser = znext;
  337.           cluser = strcspn (znext, " \t");
  338.           znext += cluser;
  339.           znext += strspn (znext, " \t");
  340.           zlsys = znext;
  341.           clsys = strcspn (znext, " \t");
  342. #else
  343.           /* The first field is system!user.  */
  344.           zlsys = znext;
  345.           clsys = strcspn (znext, "!");
  346.           znext += clsys + 1;
  347.           zlsys = znext;
  348.           clsys = strcspn (znext, " \t");
  349. #endif
  350.         }
  351.  
  352.       /* See if we should print this line.  */
  353.       if (zsystem != NULL
  354.           && (csystem != clsys
  355.           || strncmp (zsystem, zlsys, clsys) != 0))
  356.         continue;
  357.  
  358.       if (zuser != NULL
  359.           && (cuser != cluser
  360.           || strncmp (zuser, zluser, cluser) != 0))
  361.         continue;
  362.  
  363.       /* Output the line, or save it if we are outputting only a
  364.          particular number of lines.  */
  365.       if (cshow <= 0)
  366.         printf ("%s", zline);
  367.       else
  368.         {
  369.           ubuffree ((pointer) pzshow[ishow]);
  370.           pzshow[ishow] = zbufcpy (zline);
  371.           ishow = (ishow + 1) % cshow;
  372.         }
  373.     }
  374.  
  375.       /* Output the number of lines requested by the -n option.  */
  376.       if (cshow > 0)
  377.     {
  378.       for (i = 0; i < cshow; i++)
  379.         {
  380.           if (pzshow[ishow] != NULL)
  381.         printf ("%s", pzshow[ishow]);
  382.           ishow = (ishow + 1) % cshow;
  383.         }
  384.     }
  385.  
  386.       /* If -f was not specified, or an error occurred while reading
  387.      the file, get out.  */
  388.       if (! fforever || ferror (e))
  389.     break;
  390.  
  391.       clearerr (e);
  392.       cshow = 0;
  393.  
  394.       /* Sleep 1 second before going around the loop again.  */
  395.       usysdep_sleep (1);
  396.     }
  397.  
  398.   (void) fclose (e);
  399.  
  400.   ulog_close ();
  401.  
  402.   usysdep_exit (TRUE);
  403.  
  404.   /* Avoid errors about not returning a value.  */
  405.   return 0;
  406. }
  407.  
  408. /* Print a usage message and die.  */
  409.  
  410. static void
  411. ulusage ()
  412. {
  413.   fprintf (stderr,
  414.        "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n",
  415.        VERSION);
  416.   fprintf (stderr,
  417.        "Usage: uulog [-n #] [-sf system] [-u user] [-xDSF] [-I file] [-X debug]\n");
  418.   fprintf (stderr,
  419.        " -n: show given number of lines from end of log\n");
  420.   fprintf (stderr,
  421.        " -s: print entries for named system\n");
  422.   fprintf (stderr,
  423.        " -f: follow entries for named system\n");
  424.   fprintf (stderr,
  425.        " -u: print entries for named user\n");
  426. #if HAVE_HDB_LOGGING
  427.   fprintf (stderr,
  428.        " -x: print uuxqt log rather than uucico log\n");
  429. #else
  430.   fprintf (stderr,
  431.        " -F: follow entries for any system\n");
  432. #endif
  433.   fprintf (stderr,
  434.        " -S: show statistics file\n");
  435.   fprintf (stderr,
  436.        " -D: show debugging file\n");
  437.   fprintf (stderr,
  438.        " -X debug: Set debugging level (0 for none, 9 is max)\n");
  439. #if HAVE_TAYLOR_CONFIG
  440.   fprintf (stderr,
  441.        " -I file: Set configuration file to use\n");
  442. #endif /* HAVE_TAYLOR_CONFIG */
  443.   exit (EXIT_FAILURE);
  444. }
  445.